#include "FunctionBodyDescription.h"
#include "ScriptCompiler/FrameOperation/FrameOperation.h"

void CFunctionBodyDescription::AddOperation(std::shared_ptr<IFrameOperation> InOperation)
{
    Operations.Add(InOperation);
}

void CFunctionBodyDescription::InsertOperationAfter(std::shared_ptr<IFrameOperation> InNewOperation, std::shared_ptr<IFrameOperation> InAfterOperation)
{
    auto Index=Operations.Find(InAfterOperation,true);

    assert(Index.HasValue());

    Operations.Insert(Index.GetValue()+1,InNewOperation);

}

void CFunctionBodyDescription::InsertOperationBefore(std::shared_ptr<IFrameOperation> InNewOperation, std::shared_ptr<IFrameOperation> InBeforeOperation)
{
    auto Index=Operations.Find(InBeforeOperation,true);

    assert(Index.HasValue());

    Operations.Insert(Index.GetValue(),InNewOperation);
}

void CFunctionBodyDescription::RemoveOperation(std::shared_ptr<IFrameOperation> InOperation)
{
    Operations.Remove(InOperation,false);
}

TVector<std::shared_ptr<IFrameOperation>> CFunctionBodyDescription
    ::RemoveOperations(std::shared_ptr<IFrameOperation> RangeBegin
    , std::shared_ptr<IFrameOperation> RangeEnd)
{
    auto BeginIndex=Operations.Find(RangeBegin,true);
    auto EndIndex=Operations.Find(RangeEnd,true);

    assert(BeginIndex.HasValue());
    assert(EndIndex.HasValue());
    assert(BeginIndex.GetValue()<=EndIndex.GetValue());

    TVector<std::shared_ptr<IFrameOperation>> Result= Operations.Slice(
        BeginIndex.GetValue(),EndIndex.GetValue()+1);

    Operations.Remove(BeginIndex.GetValue(),EndIndex.GetValue()- BeginIndex.GetValue()+1,false );

    return Result;

}

TVector<std::shared_ptr<IFrameOperation>> CFunctionBodyDescription::RemoveOperationAndAfter(std::shared_ptr<IFrameOperation> InOperation)
{
    auto Index=Operations.Find(InOperation,true);

    assert(Index.HasValue());

    TVector<std::shared_ptr<IFrameOperation>> Result= Operations.Slice(Index.GetValue(),Operations.Num());

    Operations.RemoveAndAfter(Index.GetValue(),false);

    return Result;
}

TVector<std::shared_ptr<IFrameOperation>> CFunctionBodyDescription::RemoveAfter(std::shared_ptr<IFrameOperation> InOperation)
{
    auto Index=Operations.Find(InOperation,true);

    assert(Index.HasValue());

    TVector<std::shared_ptr<IFrameOperation>> Result;
    if(Index.GetValue()+1<Operations.Num())
    {
        Result= Operations.Slice(Index.GetValue()+1,Operations.Num());
    }

    Operations.RemoveAfter(Index.GetValue(),false);

    return Result;
}

void CFunctionBodyDescription::AddLocalVariable(std::shared_ptr<CVariableDescription> InVariable)
{
    LocalVariables.Add(InVariable);
    InVariable->Index=LocalVariables.Num()-1;
}
